/**
 * @file protocol_types.c
 * @brief 协议类型定义实现
 * @details 本文件实现了104协议的基本类型处理功能，包括时间戳、
 *          品质描述词等基本数据类型的初始化和验证。
 * 
 * @author zyb
 * @date 2025-10-01
 * @version 1.0
 * 
 * @note 所有函数都遵循104协议规范，确保严格的数据处理
 * @warning 数据转换失败时应返回相应的错误码，便于上层处理
 * 
 * @see protocol_types.h
 * @see error_codes.h
 */

#include "protocol_types.h"
#include "constants.h"
#include "../../../../../common/logs/include/logger.h"
#include <string.h>
#include <time.h>

// 定义模块名称
#define LOG_MODULE_NAME "PROTOCOL_TYPES"

/* ==================== CP56Time2a时间戳处理函数实现 ==================== */

/**
 * @brief 初始化CP56Time2a时间戳
 * @details 初始化CP56Time2a时间戳结构，设置为当前时间。
 *          用于创建新的时间戳数据。
 * 
 * @param cp56time CP56Time2a时间戳结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 初始化成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 设置为当前系统时间
 * @warning 输入指针不能为NULL
 * 
 * @see validate_cp56time2a
 * @see cp56time2a_t
 */
protocol_error_t init_cp56time2a(cp56time2a_t* cp56time) {
    LOG_DEBUG(LOG_MODULE_NAME, "初始化CP56Time2a时间戳: cp56time=%p", cp56time);
    
    if (cp56time == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "初始化CP56Time2a时间戳结构，大小: %zu", sizeof(cp56time2a_t));
    memset(cp56time, 0, sizeof(cp56time2a_t));
    
    /* 获取当前时间 */
    LOG_DEBUG(LOG_MODULE_NAME, "获取当前系统时间");
    time_t now = time(NULL);
    struct tm* tm_info = localtime(&now);
    
    if (tm_info != NULL) {
        LOG_DEBUG(LOG_MODULE_NAME, "系统时间转换成功: %04d-%02d-%02d %02d:%02d:%02d", 
                  tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday,
                  tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec);
        
        cp56time->year = (tm_info->tm_year + 1900) % 100; /* 转换为0-99格式 */
        cp56time->month = tm_info->tm_mon + 1;
        cp56time->day_of_month = tm_info->tm_mday;
        cp56time->hours = tm_info->tm_hour;
        cp56time->minutes = tm_info->tm_min;
        cp56time->day_of_week = tm_info->tm_wday == 0 ? 7 : tm_info->tm_wday; /* 转换为1-7格式 */
        cp56time->milliseconds = 0; /* 毫秒设为0 */
        
        LOG_DEBUG(LOG_MODULE_NAME, "CP56Time2a时间戳设置完成: 年=%d, 月=%d, 日=%d, 时=%d, 分=%d, 星期=%d, 毫秒=%d", 
                  cp56time->year, cp56time->month, cp56time->day_of_month, 
                  cp56time->hours, cp56time->minutes, cp56time->day_of_week, cp56time->milliseconds);
        
        LOG_INFO(LOG_MODULE_NAME, "CP56Time2a时间戳初始化成功: %02d-%02d-%02d %02d:%02d:%02d", 
                 cp56time->year, cp56time->month, cp56time->day_of_month, 
                 cp56time->hours, cp56time->minutes, cp56time->milliseconds);
    } else {
        LOG_ERROR(LOG_MODULE_NAME, "localtime转换失败，使用默认值");
        LOG_WARN(LOG_MODULE_NAME, "CP56Time2a时间戳使用默认值初始化");
    }
    
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证CP56Time2a时间戳
 * @details 验证CP56Time2a时间戳结构的完整性和有效性。
 *          检查所有字段的有效性。
 * 
 * @param cp56time CP56Time2a时间戳结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 验证所有字段的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see init_cp56time2a
 * @see cp56time2a_t
 */
protocol_error_t validate_cp56time2a(const cp56time2a_t* cp56time) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证CP56Time2a时间戳: cp56time=%p", cp56time);
    
    if (cp56time == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证年份 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证年份: %d", cp56time->year);
    if (cp56time->year > 99) {
        LOG_ERROR(LOG_MODULE_NAME, "年份无效: %d > 99", cp56time->year);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证月份 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证月份: %d", cp56time->month);
    if (cp56time->month < 1 || cp56time->month > 12) {
        LOG_ERROR(LOG_MODULE_NAME, "月份无效: %d (范围: 1-12)", cp56time->month);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证日期 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证日期: %d", cp56time->day_of_month);
    if (cp56time->day_of_month < 1 || cp56time->day_of_month > 31) {
        LOG_ERROR(LOG_MODULE_NAME, "日期无效: %d (范围: 1-31)", cp56time->day_of_month);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证小时 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证小时: %d", cp56time->hours);
    if (cp56time->hours > 23) {
        LOG_ERROR(LOG_MODULE_NAME, "小时无效: %d > 23", cp56time->hours);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证分钟 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证分钟: %d", cp56time->minutes);
    if (cp56time->minutes > 59) {
        LOG_ERROR(LOG_MODULE_NAME, "分钟无效: %d > 59", cp56time->minutes);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证星期 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证星期: %d", cp56time->day_of_week);
    if (cp56time->day_of_week < 1 || cp56time->day_of_week > 7) {
        LOG_ERROR(LOG_MODULE_NAME, "星期无效: %d (范围: 1-7)", cp56time->day_of_week);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证毫秒 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证毫秒: %d", cp56time->milliseconds);
    if (cp56time->milliseconds > 59999) {
        LOG_ERROR(LOG_MODULE_NAME, "毫秒无效: %d > 59999", cp56time->milliseconds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "CP56Time2a时间戳验证通过");
    return PROTOCOL_SUCCESS;
}

/* ==================== QDS品质描述词处理函数实现 ==================== */

/**
 * @brief 初始化QDS品质描述词
 * @details 初始化QDS品质描述词结构，设置为默认值。
 *          用于创建新的品质描述词数据。
 * 
 * @param qds QDS品质描述词结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 初始化成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 设置为默认值（有效、当前值、非替代、非闭锁、无溢出）
 * @warning 输入指针不能为NULL
 * 
 * @see validate_qds
 * @see qds_t
 */
protocol_error_t init_qds(qds_t* qds) {
    LOG_DEBUG(LOG_MODULE_NAME, "初始化QDS品质描述词: qds=%p", qds);
    
    if (qds == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "初始化QDS品质描述词结构，大小: %zu", sizeof(qds_t));
    memset(qds, 0, sizeof(qds_t));
    
    /* 设置为默认值（有效、当前值、非替代、非闭锁、无溢出） */
    LOG_DEBUG(LOG_MODULE_NAME, "设置QDS默认值");
    qds->iv = 0;  /* 有效 */
    qds->nt = 0;  /* 当前值 */
    qds->sb = 0;  /* 非替代 */
    qds->bl = 0;  /* 非闭锁 */
    qds->ov = 0;  /* 无溢出 */
    
    LOG_INFO(LOG_MODULE_NAME, "QDS品质描述词初始化完成");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证QDS品质描述词
 * @details 验证QDS品质描述词结构的完整性和有效性。
 *          检查所有字段的有效性。
 * 
 * @param qds QDS品质描述词结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 验证所有字段的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see init_qds
 * @see qds_t
 */
protocol_error_t validate_qds(const qds_t* qds) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证QDS品质描述词: qds=%p", qds);
    
    if (qds == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证品质描述词的有效性 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证QDS品质描述词字段");
    LOG_DEBUG(LOG_MODULE_NAME, "QDS字段: iv=%d, nt=%d, sb=%d, bl=%d, overflow=%d", 
              qds->iv, qds->nt, qds->sb, qds->bl, qds->ov);
    
    /* 这里可以根据具体需求添加验证逻辑 */
    LOG_DEBUG(LOG_MODULE_NAME, "QDS品质描述词验证通过");
    
    LOG_INFO(LOG_MODULE_NAME, "QDS品质描述词验证完成");
    return PROTOCOL_SUCCESS;
}

/* ==================== 信息对象地址处理函数实现 ==================== */

/**
 * @brief 验证信息对象地址
 * @details 验证信息对象地址的有效性。
 *          检查地址是否在有效范围内。
 * 
 * @param address 信息对象地址
 * @return 验证结果
 *         - 1: 地址有效
 *         - 0: 地址无效
 * 
 * @note 地址范围：1-16777215
 * @warning 地址不能为0
 * 
 * @see info_addr_t
 */
/* is_info_address_valid is implemented in validation_utils.c */

/* ==================== APDU处理函数实现 ==================== */

/**
 * @brief 初始化APDU
 * @details 初始化APDU（应用协议数据单元）结构，设置为默认值。
 *          该函数会清零整个APDU结构，并设置启动字符和最小长度。
 *          用于创建新的APDU数据包。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 初始化成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 设置启动字符为APDU_START_CHAR，长度为APDU_MIN_LENGTH
 * @warning 输入指针不能为NULL
 * 
 * @see validate_apdu
 * @see apdu_t
 * @see APDU_START_CHAR
 * @see APDU_MIN_LENGTH
 */
protocol_error_t init_apdu(apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "初始化APDU: apdu=%p", apdu);
    
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "初始化APDU结构，大小: %zu", sizeof(apdu_t));
    memset(apdu, 0, sizeof(apdu_t));
    apdu->start = APDU_START_CHAR;
    apdu->length = APDU_MIN_LENGTH;
    LOG_DEBUG(LOG_MODULE_NAME, "设置APDU默认值: start=0x%02X, length=%d", apdu->start, apdu->length);
    
    LOG_INFO(LOG_MODULE_NAME, "APDU初始化完成");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证APDU
 * @details 验证APDU（应用协议数据单元）结构的有效性。
 *          该函数会检查启动字符和长度字段是否符合104协议规范。
 *          用于确保APDU数据包的格式正确。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 验证启动字符和长度字段的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see init_apdu
 * @see apdu_t
 * @see APDU_START_CHAR
 * @see APDU_MIN_LENGTH
 * @see APDU_MAX_LENGTH
 */
protocol_error_t validate_apdu(const apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证APDU: apdu=%p", apdu);
    
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证APDU启动字符: 0x%02X", apdu->start);
    if (apdu->start != APDU_START_CHAR) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的启动字符: 0x%02X, 期望: 0x%02X", apdu->start, APDU_START_CHAR);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证APDU长度: %d", apdu->length);
    if (apdu->length < APDU_MIN_LENGTH || apdu->length > APDU_MAX_LENGTH) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的APDU长度: %d (范围: %d-%d)", apdu->length, APDU_MIN_LENGTH, APDU_MAX_LENGTH);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "APDU验证通过");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 检查是否为I格式APDU
 * @details 检查APDU是否为I格式（信息传输格式）。
 *          I格式用于传输信息对象，包含发送序号和接收序号。
 *          通过检查控制域第1字节的bit0和bit1是否为0来判断。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @return 检查结果
 *         - 1: 是I格式APDU
 *         - 0: 不是I格式APDU或参数无效
 * 
 * @note I格式特征：控制域第1字节的bit0=0且bit1=0
 * @warning 输入指针不能为NULL
 * 
 * @see is_s_format_apdu
 * @see is_u_format_apdu
 * @see apdu_t
 */
int is_i_format_apdu(const apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "检查I格式APDU: apdu=%p", apdu);
    
    // 检查输入参数是否为空
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    // 检查控制域第1字节的bit0和bit1是否为0（I格式特征）
    int result = ((apdu->control_field.control1 & 0x01) == 0) && 
                 ((apdu->control_field.control1 & 0x02) == 0);
    
    LOG_DEBUG(LOG_MODULE_NAME, "I格式APDU检查结果: %d (control1=0x%02X)", result, apdu->control_field.control1);
    LOG_INFO(LOG_MODULE_NAME, "I格式APDU检查完成: %s", result ? "是I格式" : "不是I格式");
    return result;
}

/**
 * @brief 检查是否为S格式APDU
 * @details 检查APDU是否为S格式（监视格式）。
 *          S格式用于传输监视信息，只包含接收序号。
 *          通过检查控制域第1字节的bit0、bit1和bit2是否为0来判断。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @return 检查结果
 *         - 1: 是S格式APDU
 *         - 0: 不是S格式APDU或参数无效
 * 
 * @note S格式特征：控制域第1字节的bit0=0、bit1=0且bit2=0
 * @warning 输入指针不能为NULL
 * 
 * @see is_i_format_apdu
 * @see is_u_format_apdu
 * @see apdu_t
 */
int is_s_format_apdu(const apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "检查S格式APDU: apdu=%p", apdu);
    
    // 检查输入参数是否为空
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    // 检查控制域第1字节的bit0、bit1和bit2是否为0（S格式特征）
    int result = ((apdu->control_field.control1 & 0x01) == 0) && 
                 ((apdu->control_field.control1 & 0x02) == 0) &&
                 ((apdu->control_field.control1 & 0x04) == 0);
    
    LOG_DEBUG(LOG_MODULE_NAME, "S格式APDU检查结果: %d (control1=0x%02X)", result, apdu->control_field.control1);
    LOG_INFO(LOG_MODULE_NAME, "S格式APDU检查完成: %s", result ? "是S格式" : "不是S格式");
    return result;
}

/**
 * @brief 检查是否为U格式APDU
 * @details 检查APDU是否为U格式（控制格式）。
 *          U格式用于传输控制信息，如启动、停止、测试等。
 *          通过检查控制域第1字节的bit0、bit1、bit2和bit3是否为0来判断。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @return 检查结果
 *         - 1: 是U格式APDU
 *         - 0: 不是U格式APDU或参数无效
 * 
 * @note U格式特征：控制域第1字节的bit0=0、bit1=0、bit2=0且bit3=0
 * @warning 输入指针不能为NULL
 * 
 * @see is_i_format_apdu
 * @see is_s_format_apdu
 * @see apdu_t
 */
int is_u_format_apdu(const apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "检查U格式APDU: apdu=%p", apdu);
    
    // 检查输入参数是否为空
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    // 检查控制域第1字节的bit0、bit1、bit2和bit3是否为0（U格式特征）
    int result = ((apdu->control_field.control1 & 0x01) == 0) && 
                 ((apdu->control_field.control1 & 0x02) == 0) &&
                 ((apdu->control_field.control1 & 0x04) == 0) &&
                 ((apdu->control_field.control1 & 0x08) == 0);
    
    LOG_DEBUG(LOG_MODULE_NAME, "U格式APDU检查结果: %d (control1=0x%02X)", result, apdu->control_field.control1);
    LOG_INFO(LOG_MODULE_NAME, "U格式APDU检查完成: %s", result ? "是U格式" : "不是U格式");
    return result;
}

/* ==================== ASDU处理函数实现 ==================== */

/**
 * @brief 初始化ASDU
 * @details 初始化ASDU（应用服务数据单元）结构，设置为默认值。
 *          该函数会清零整个ASDU结构，用于创建新的ASDU数据包。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 初始化成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 清零整个ASDU结构
 * @warning 输入指针不能为NULL
 * 
 * @see validate_asdu
 * @see asdu_t
 */
protocol_error_t init_asdu(asdu_t* asdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "初始化ASDU: asdu=%p", asdu);
    
    if (asdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "初始化ASDU结构，大小: %zu", sizeof(asdu_t));
    memset(asdu, 0, sizeof(asdu_t));
    
    LOG_INFO(LOG_MODULE_NAME, "ASDU初始化完成");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证ASDU
 * @details 验证ASDU（应用服务数据单元）结构的有效性。
 *          该函数会检查类型标识和公共地址字段是否符合104协议规范。
 *          用于确保ASDU数据包的格式正确。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 验证类型标识和公共地址字段的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see init_asdu
 * @see asdu_t
 */
protocol_error_t validate_asdu(const asdu_t* asdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证ASDU: asdu=%p", asdu);
    
    if (asdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证ASDU类型标识: %d", asdu->type_id);
    if (asdu->type_id == 0) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的类型标识: %d", asdu->type_id);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证ASDU公共地址: %d", asdu->common_address);
    if (asdu->common_address == 0) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的公共地址: %d", asdu->common_address);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "ASDU验证通过");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证APDU长度
 * @details 验证APDU长度是否在有效范围内。
 *          根据104协议规范，APDU长度必须在最小长度和最大长度之间。
 * 
 * @param length APDU长度值
 * @return 验证结果
 *         - 1: 长度有效
 *         - 0: 长度无效
 * 
 * @note 长度范围：APDU_MIN_LENGTH 到 APDU_MAX_LENGTH
 * @warning 长度超出范围会导致协议错误
 * 
 * @see APDU_MIN_LENGTH
 * @see APDU_MAX_LENGTH
 * @see validate_apdu
 */
int is_apdu_length_valid(u8 length) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证APDU长度: %d", length);
    
    // 检查APDU长度是否在有效范围内
    int result = (length >= APDU_MIN_LENGTH && length <= APDU_MAX_LENGTH);
    LOG_DEBUG(LOG_MODULE_NAME, "APDU长度验证结果: %d (范围: %d-%d)", result, APDU_MIN_LENGTH, APDU_MAX_LENGTH);
    LOG_INFO(LOG_MODULE_NAME, "APDU长度验证完成: %s (长度: %d)", result ? "有效" : "无效", length);
    
    return result;
}

/**
 * @brief 验证APDU控制域
 * @details 验证APDU控制域是否有效。
 *          该函数会检查控制域的4个字节是否合理，
 *          至少有一个字节不为0表示控制域有效。
 * 
 * @param control_field APDU控制域结构指针，不能为NULL
 * @return 验证结果
 *         - 1: 控制域有效
 *         - 0: 控制域无效或参数无效
 * 
 * @note 基本验证：至少有一个控制域字节不为0
 * @warning 输入指针不能为NULL
 * 
 * @see apdu_control_field_t
 * @see validate_apdu
 */
int is_apdu_control_valid(const apdu_control_field_t* control_field) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证APDU控制域: control_field=%p", control_field);
    
    // 检查输入参数是否为空
    if (control_field == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    // 基本验证：检查控制域字节是否合理（至少有一个字节不为0）
    int result = (control_field->control1 != 0 || control_field->control2 != 0 ||
            control_field->control3 != 0 || control_field->control4 != 0);
    
    LOG_DEBUG(LOG_MODULE_NAME, "APDU控制域验证结果: %d (control1=0x%02X, control2=0x%02X, control3=0x%02X, control4=0x%02X)", 
              result, control_field->control1, control_field->control2, control_field->control3, control_field->control4);
    LOG_INFO(LOG_MODULE_NAME, "APDU控制域验证完成: %s", result ? "有效" : "无效");
    
    return result;
}

/* ==================== APDU格式检测函数实现 ==================== */

/**
 * @brief 检测APDU格式类型
 * @details 根据控制域检测APDU的格式类型（I格式、S格式、U格式）
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @return APDU格式类型
 *         - APDU_FORMAT_I: I格式APDU
 *         - APDU_FORMAT_S: S格式APDU
 *         - APDU_FORMAT_U: U格式APDU
 *         - APDU_FORMAT_INVALID: 无效格式
 * 
 * @note 根据控制域第1字节的最低位判断格式类型
 * @warning 输入指针不能为NULL
 */
apdu_format_t detect_apdu_format(const apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "检测APDU格式: apdu=%p", apdu);
    
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return APDU_FORMAT_INVALID;
    }
    
    // 根据控制域第1字节的最低位判断格式类型
    if ((apdu->control_field.control1 & 0x01) == 0) {
        LOG_DEBUG(LOG_MODULE_NAME, "检测到I格式APDU");
        return APDU_FORMAT_I;
    } else if ((apdu->control_field.control1 & 0x03) == 0x01) {
        LOG_DEBUG(LOG_MODULE_NAME, "检测到S格式APDU");
        return APDU_FORMAT_S;
    } else if ((apdu->control_field.control1 & 0x03) == 0x03) {
        LOG_DEBUG(LOG_MODULE_NAME, "检测到U格式APDU");
        return APDU_FORMAT_U;
    } else {
        LOG_ERROR(LOG_MODULE_NAME, "无效的APDU格式，控制域1: 0x%02X", apdu->control_field.control1);
        return APDU_FORMAT_INVALID;
    }
}
